/*
数据结构
1.Set用法：当做数组来用，但是里面的元素是不能够重复的
2.WeakSet用法  （引用）
3.Map用法：key一定是字符串，key可以是任意的一个数据类型
4.WeakMap的用法
*/

{
  //set普通定义方法
  let list = new Set();
  list.add(5);
  list.add(7);
  console.log('size',list.size);//size 2
  //set另外的一个定义方式，也就是默认值的意思
  let arr = [1,2,3,4,5]
  let list2=new Set(arr)
  console.log('size',list2.size);//size  5
}

{
//set里面的元素是唯一的
let list = new Set();
list.add(1);
list.add(2);
list.add(1);
//添加重复的元素不会报错，只是不生效而已，最大的作用是：去重
console.log(list.size);  //2

let arr=[1,2,3,4,5,1,3,5,4,'2','5'];
let list2=new Set(arr);
console.log(list2);//{1,2,3,4,5,36}
//但是在这里：转换元素的时候不会做数据类型的转换
}

{
  //set实例的几个方法  1.添加元素：add；2.删除元素：delete；3.清除元素：clear；4.判断是否存在这个元素：has
  let arr=['add','delect','clear','has'];
  let list=new Set(arr);
  // console.log(list.has('add'))
  // console.log(list.delete('add'));
  // list.clear();
  // console.log(list);
  //set 怎么读取里面的元素呀 怎么做遍历  key=value  默认遍历出来的是value
  for(let key of list.keys()){
    console.log(key);
  }
  for(let value of list.values()){
    console.log(value);
  }
  for(let [key,value] of Object(list).entries()){
    console.log('entries',key,value);
  }
  list.forEach(function(item){
    console.log('forEach',item);
  })
}

{
  /*
  WeakSet和Set 有什么区别?
    1.WeakSet和 Set支持的数据类型不一样；WeakSet的对象类型只能是对象，不能是其他的数据类型；
    2.WeakSet的对象是弱引用，不能检测，他在其他地方是否存在，跟垃圾回收机制一点也不挂钩；
    3.有一些属性和方法是set没有的
  */
  let wesetList=new WeakSet();
  let arg={};
  wesetList.add(arg)
  console.log('wesetList',wesetList);//wesetList{{}}
  // wesetList.add(2)
  //console.log('wesetList2',wesetList);index.js:228 Uncaught TypeError: Invalid value used in weak set
//没有clear方法 没有size属性  不能遍历  但是其他的  add  delect has 方法是有的
}


{
  //map  用set方法给他设置属性；有get方法获取属性
  let map = new Map();
  let arr=[1,2,3];
  console.log(map);
  map.set(arr,569);
  console.log(map);//{Array(3) => 569}
  console.log(map.get(arr));//569
}

{
  let map=new Map([['a','123'],['b','456']]);
  console.log(map);//{"a" => "123", "b" => "456"}
  console.log(map.get('a'));//123
  map.set('a','589')
  console.log(map.get('a'));//589
  console.log(map.size);//2
  map.delete('a')
  console.log(map);// {"b" => "456"}
  map.clear();
  console.log(map); //{}
  //遍历的方法也是set方法一样的
}

{
  let weakmap=new WeakMap();
  let obj={}
  weakmap.set(obj,'asd')
  console.log(weakmap);//{Object => "asd"}
  console.log(weakmap.get(obj));//asd
}

/*
Map和Array的对比  Set和Array的对比
*/

{
//数据结构的横向对比，增，查，删，改
let map =new Map();
let arr=[];
//增
map.set('t',1);
arr.push({t:1});
console.info('map-arr-add',map,arr)
//查
let map_exist=map.has('t');
let arr_exist=arr.find(item=>item.t);
//数组是返回查找到这个对象，  但是map返回的是布尔值
console.info('map-arr-find',map_exist,arr_exist)// true {t: 1}
//改
map.set('t',2);
arr.forEach(item=>item.t ? item.t=2:'')
console.info('map-arr-change',map,arr)
//删
map.delete('t')
let index = arr.findIndex(item=>item.t);
arr.splice(index,1)
console.log('map-arr-delect',map,arr);// {} []
}

{
  let set=new Set();
  let arr=[];
  //增
  set.add({t:1});
  arr.push({t:1})
  console.log('set-arr-add',set,arr);
  //查
  let set_exist=set.has({t:1});
  let arr_exist=arr.find(item=>item.t);
  console.log('set-arr-find',set_exist,arr_exist);//false  {t:1}
  //改
  set.forEach(item=>item.t ? item.t=2:'')
  arr.forEach(item=>item.t ? item.t=2:'')
  console.info('map-arr-change',set,arr)
  //删
  set.forEach(item=>item.t?set.delete(item):'')
  let index = arr.findIndex(item=>item.t);
  arr.splice(index,1)
  console.log('set-arr-delect',set,arr);// {} []
}

{
  /*
Map和 Object  Set和Object 的对比
  */
let item ={t:1};
let map=new Map();
let set =new Set();
let obj={};
//增
map.set('t',1);
set.add(item);
obj['t']=1;
console.log(map,set,obj);
//查
console.info({
  map_exsit:map.has('t'),
  set_exsit:set.has(item),
  obj_exsit:'t' in obj
});//true,true,true
//改
map.set('t',2);
item.t=2;
obj['t']=2;
console.log(map,set,obj);
//删
map.delete('t');
set.delete(item);
delete obj['t'];
console.log(map,set,obj);
}

/*
总结:
1.map数据结构比较方便  优先使用map
2.如果要考虑数据的唯一性的话那么建议用set
3.建议放弃用Object和Array做数据存储
*/
